Skip to content

Conversation

rjmccall
Copy link
Contributor

@rjmccall rjmccall commented Oct 4, 2025

The previous algorithm was doing an iterative forward data flow analysis followed by a reverse data flow analysis. I suspect the history here is that it was a reverse analysis, and that didn't really work for infinite loops, and so complexity kindof accumulated.

The new algorithm is quite straightforward and relies on the allocations being properly jointly post-dominated, just not nested. We simply walk forward through the blocks in consistent-with-dominance order, maintaining the stack of active allocations and deferring deallocations that are improperly nested until we deallocate the allocations above it.

The reason I'm doing this, besides it just being a simpler, faster algorithm, is that modeling some of the uses of the async stack allocator properly requires builtins that cannot just be semantically reordered. That should be somewhat easier to handle with the new approach, although really (1) we should not have runtime functions that need this and (2) we're going to need a conservatively-correct solution that's different from this anyway because hoisting allocations is also limited in its own way.

The test cases that changed are... I don't think the new output is wrong under the current rules that are being enforced, but really we should be enforcing different rules, because it's not really okay to have broken stack nesting in blocks just because they don't lead to an exit. But it's broken coming into StackNesting, and I don't think the rewrite actually makes it worse, so...

The thing that concerns me most about the rewritten pass is that it isn't actually validating joint post-dominance on input, so if you give it bad input, it might be a little mystifying to debug the verifier failures.

@rjmccall
Copy link
Contributor Author

rjmccall commented Oct 4, 2025

@swift-ci Please test


dealloc_stack %the_array: $*Array<Int>
%24 = tuple ()
return %24 : $()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the past we used stack promotion to test fixStackNesting. However, today we can write unit tests using FunctionTest. It would be good to add such tests for this new StackNesting implementation.

The previous algorithm was doing an iterative forward data flow
analysis followed by a reverse data flow analysis. I suspect the
history here is that it was a reverse analysis, and that didn't
really work for infinite loops, and so complexity kindof accumulated.

The new algorithm is quite straightforward and relies on the
allocations being properly jointly post-dominated, just not nested.
We simply walk forward through the blocks in consistent-with-dominance
order, maintaining the stack of active allocations and deferring
deallocations that are improperly nested until we deallocate the
allocations above it.

The reason I'm doing this, besides it just being a simpler, faster
algorithm, is that modeling some of the uses of the async stack
allocator properly requires builtins that cannot just be semantically
reordered. That should be somewhat easier to handle with the new
approach, although really (1) we should not have runtime functions
that need this and (2) we're going to need a conservatively-correct
solution that's different from this anyway because hoisting
allocations is *also* limited in its own way.

The test cases that changed are... I don't think the new output
is wrong under the current rules that are being enforced, but
really we should be enforcing different rules, because it's not
really okay to have broken stack nesting in blocks just because
they don't lead to an exit. But it's broken coming into
StackNesting, and I don't think the rewrite actually makes it
worse, so...

The thing that concerns me most about the rewritten pass is that
it isn't actually validating joint post-dominance on input, so
if you give it bad input, it might be a little mystifying to
debug the verifier failures.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants